11.1 Set
说明:类似于数组,但是成员的值都是唯一的,没有重复的值
11.1.1 基本用法
说明:向Set
加入值的时候,Set内部判断两个值是否不同,使用的算法叫做Same-value equality
,它类似于===
,主要的区别是NaN
等于自身,而===
认为NaN不等于自身
要点
- 通过
Set
构造器创建实例(可以传入数组来初始化) - 使用
add
实例方法添加成员
技巧:一种去除数组重复成员的方法[...new Set(array)]
Demo1: 通过 add 为 set 实例添加成员
1 | var s = new Set(); |
Demo2: 接受一个数组(或类似数组的对象)作为参数,用来初始化
1 | // 例一 |
11.1.2 Set 实例的属性和方法
11.1.2.1 实例属性
实例属性 | 类型 | 说明 |
---|---|---|
Set.prototype.constructor |
function |
构造函数,默认就是Set 函数 |
Set.prototype.size |
number |
Set 实例的成员总数 |
11.1.2.2 操作方法
操作方法 | 说明 |
---|---|
add(value) |
添加某个值,返回Set结构本身 |
delete(value) |
删除某个值,返回一个布尔值,表示删除是否成功 |
has(value) |
返回一个布尔值,表示该值是否为Set的成员 |
clear() |
清除所有成员,没有返回值 |
Demo1: 操作方法的基本使用
1 | s.add(1).add(2).add(2); |
Demo2: Array.from
方法可以将Set
结构转为数组
1 | var items = new Set([1, 2, 3, 4, 5]); |
Demo3: 去除数组重复成员(也可以通过扩展运算符(...
)
1 | function dedupe(array) { |
11.1.2.3 遍历方法
顺序:Set
的遍历顺序就是插入顺序
注意:由于Set
结构的键名的键名和键值是同一个值,所以keys
方法和values
方法的行为完全一致
技巧:Set
结构的实例默认可遍历,它的默认遍历器生成函数就是它的values
方法,因此,可以省略values
方法,直接用for...of
循环遍历Set
遍历相关实例方法 | 说明 |
---|---|
keys() |
返回键名的遍历器 |
values() |
返回键值的遍历器 |
entries() |
返回键值对的遍历器 |
forEach() |
使用回调函数遍历每个成员,和数组的forEach 用法一样 |
Demo1: keys(),values(),entries()
1 | let set = new Set(['red', 'green', 'blue']); |
Demo2: 省略values
方法,直接用for...of
循环遍历Set
1 | let set = new Set(['red', 'green', 'blue']); |
Demo3: forEach
方法
1 | let set = new Set([1, 2, 3]); |
Demo4: 遍历的应用
...
和set
结合,去除数组的重复成员
1 | let arr = [3, 5, 2, 2, 5, 5]; |
- 转换为数组后,
map
和filter
方法也可以用于Set
了
1 | let set = new Set([1, 2, 3]); |
- 集合运算
1 | let a = new Set([1, 2, 3]); |
11.2 WeakSet
说明:Set
的弱引用版本
WeakSet
的成员只能是对象
- 垃圾回收机制不考虑
WeakSet
对成员的引用 WeakSet
是不可遍历的(因为无法引用WeakSet
的成员)
技巧:WeakSet
的一个用处,是储存DOM
节点,而不用担心这些节点从文档移除时,会引发内存泄漏
11.2.1 构造器
说明:WeakSet
是一个构造函数,可以使用new
命令,创建WeakSet
数据结构
参数 | 类型 | 说明 | 必需 |
---|---|---|---|
1 | iterable接口 |
一个数组或类似数组的对象(成员必须是对象) | 否 |
1 | var a = [[1,2], [3,4]]; |
11.2.2 实例方法
实例方法 | 说明 |
---|---|
WeakSet.prototype.add(value) |
向WeakSet 实例添加一个新成员 |
WeakSet.prototype.delete(value) |
清除WeakSet 实例的指定成员 |
WeakSet.prototype.has(value) |
返回一个布尔值,表示某个值是否在WeakSet 实例之中 |
1 | var ws = new WeakSet(); |
11.3 Map
说明:ES6
提供了Map
数据结构。它类似于对象,也是键值对的集合,但是键
的范围不限于字符串
,各种类型的值(包括对象)都可以当作键
11.3.1 Map 结构的目的和基本用法
说明:Map
结构提供了值—值
的对应,是一种更完善的Hash
结构实现。如果你需要键值对
的数据结构,Map
比Object
更合适
Map 构造器
参数 | 类型 | 说明 | 必需 |
---|---|---|---|
1 | array |
该数组的成员是一个个表示键值对的数组 | 否 |
注意:Map
区分不同键的方式类似===
键类型 | 判断标准 |
---|---|
引用类型 |
Map 的键跟内存地址绑定的,只要内存地址不一样,就视为两个键 |
number、string、boolean |
只要两个值严格相等,就视为一个键(包括0 和-0 ) |
NaN |
Map 将其视为同一个键(虽然NaN 不严格相等于自身) |
1 | var map = new Map([ |
11.3.2 实例的属性和操作方法
实例属性 | 类型 | 说明 |
---|---|---|
size |
number |
Map 结构的成员总数 |
实例方法 | 说明 |
---|---|
set(key, value) |
如果key已经有值,则键值会被更新,否则就新生成该键。返回整个Map 结构,因此可以采用链式写法 |
get(key) |
读取key 对应的键值,如果找不到key ,返回undefined |
has(key) |
返回一个布尔值,表示某个键是否在Map 数据结构中 |
delete(key) |
删除某个键,返回true 。如果删除失败,返回false |
clear() |
清除所有成员,没有返回值 |
1 | let map = new Map() |
11.3.3 遍历方法
说明:Map结构本身就可以遍历,默认的遍历器接口为Map.prototype.entries()
注意:Map
的遍历顺序就是插入顺序
遍历方法 | 说明 |
---|---|
keys() |
返回键名的遍历器 |
values() |
返回键值的遍历器 |
entries() |
返回所有成员的遍历器 |
forEach() |
遍历Map 的所有成员 |
Demo1: 基本使用
1 | let map = new Map([ |
Demo2: Map结构的默认遍历器接口(Symbol.iterator属性),就是entries方法
1 | map[Symbol.iterator] === map.entries |
Demo3: 结合使用扩展运算符,将Map结构转为数组结构,实现Map的遍历和过滤
1 | let map0 = new Map() |
Map.prototype.forEach()
说明:和数组的forEach()
方法用法一致(还可以接受第二个参数,用来绑定this
)
1 | map.forEach(function(value, key, map) { |
11.3.4 与其他数据结构的互相转换
(1) Map
转为数组
:使用扩展运算符
1 | let myMap = new Map().set(true, 7).set({foo: 3}, ['abc']); |
(2) 数组
转为Map
(数组的成员为有两个成员的数组)
1 | new Map([[true, 7], [{foo: 3}, ['abc']]]) |
(3) Map
转为对象
(前提是所有Map
的键都是字符串)
1 | function strMapToObj(strMap) { |
(4) 对象
转为Map
1 | function objToStrMap(obj) { |
(5) Map
转为JSON
:分两种情况
1)转为对象JSON
(Map
的键名都是字符串):Map
-> 对象
-> JSON
1 | function strMapToJson(strMap) { |
2)转为数组JSON
(Map
的键名有非字符串):Map
-> 数组
-> JSON
1 | function mapToArrayJson(map) { |
(6) JSON
转为Map
1)JSON
->对象
->Map
(一般情形)
1 | function jsonToStrMap(jsonStr) { |
2)JSON
->数组
->Map
字符串的格式(JSON
可以转换为情景2
的数组)
1 | function jsonToMap(jsonStr) { |
11.4 WeakMap
设计目的:key
是对象的弱引用(垃圾回收机制不将该引用考虑在内),所以其所对应的对象可能会被自动回收。当key
被回收后,WeakMap
自动移除对应的键值对,从而防止内存泄漏。
用途:WeakMap
的专用场合就是,它的键所对应的对象,可能会在将来消失。
说明:WeakMap
与Map
在API上的区别
- 没有遍历操作(即没有key()、values()和entries()方法)
- 没有
size
属性 - 无法清空(即不支持
clear
方法) - 只有四个方法可用:
get()、set()、has()、delete()
Demo1: 基本用法
1 | var wm = new WeakMap(); |
Demo2: DOM节点作为键名
1 | let myElement = document.getElementById('logo'); |
Demo3: 部署私有属性Countdown
类的两个内部属性_counter
和_action
,是实例的弱引用,所以如果删除实例,它们也就随之消失,不会造成内存泄漏
1 | let _counter = new WeakMap(); |